

import 'dart:ui' as ui;
import 'package:equatable/equatable.dart';
import '../../core/constants.dart';

/// 拼图块数据模型 (已修改，持有独立的图像数据)
class PuzzlePiece extends Equatable {
  /// 唯一标识符
  final int id;
  
  /// 正确的网格位置
  final int correctRow;
  final int correctCol;

  /// 新增：持有裁剪后的独立小图
  final ui.Image image;
  
  /// 当前的网格位置（用于逻辑计算）
  final int currentRow;
  final int currentCol;
  
  /// 屏幕上的像素位置
  final ui.Offset position;
  
  /// 拼图块的逻辑尺寸
  final ui.Size size;
  
  /// 是否已正确放置
  final bool isPlaced;
  
  /// 是否被选中（用于高亮显示）
  final bool isSelected;
  
  /// 是否锁定（已放置的拼图块不可再移动）
  final bool isLocked;
  
  /// 拼图块的裁剪路径（现在已不再重要）
  final ui.Path clipPath;
  
  /// 拼图块的旋转角度（V2.0功能预留）
  final double rotation;
  
  /// Z轴层级（控制显示顺序，拖拽时提升层级）
  final int zIndex;
  
  const PuzzlePiece({
    required this.id,
    required this.correctRow,
    required this.correctCol,
    required this.image,
    required this.currentRow,
    required this.currentCol,
    required this.position,
    required this.size,
    required this.clipPath,
    this.isPlaced = false,
    this.isSelected = false,
    this.isLocked = false,
    this.rotation = 0.0,
    this.zIndex = 0,
  });
  
  /// 是否在正确的网格位置 (已修复笔误)
  bool get isInCorrectPosition => 
      correctRow == currentRow && correctCol == currentCol;
  
  /// 是否已正确放置（兼容GameViewModel）
  bool get isCorrectlyPlaced => isInCorrectPosition && isPlaced;
  
  /// 是否在游戏区域（而不是散落区域）
  bool get isInGameArea => currentRow != -1 && currentCol != -1;
  
  /// 计算正确的屏幕位置
  ui.Offset get correctScreenPosition {
    const boardOffset = ui.Offset(50, 100); // 拼图面板的偏移量
    return ui.Offset(
      boardOffset.dx + correctCol * size.width,
      boardOffset.dy + correctRow * size.height,
    );
  }
  
  /// 计算与正确位置的距离
  double get distanceToCorrectPosition {
    return (position - correctScreenPosition).distance;
  }
  
  /// 是否接近正确位置（在吸附阈值内）
  bool get isNearCorrectPosition {
    return distanceToCorrectPosition < AppConstants.snapThreshold;
  }
  
  /// 获取拼图块的中心点
  ui.Offset get center => ui.Offset(
    position.dx + size.width / 2,
    position.dy + size.height / 2,
  );
  
  /// 获取拼图块的边界矩形
  ui.Rect get bounds => ui.Rect.fromLTWH(
    position.dx,
    position.dy,
    size.width,
    size.height,
  );
  
  /// 创建副本，用于状态更新
  PuzzlePiece copyWith({
    int? currentRow,
    int? currentCol,
    ui.Offset? position,
    bool? isPlaced,
    bool? isSelected,
    bool? isLocked,
    double? rotation,
    int? zIndex,
    // image 不需要 copy, 因为它是 final 且在创建后不变
  }) {
    return PuzzlePiece(
      id: id,
      correctRow: correctRow,
      correctCol: correctCol,
      image: image,
      currentRow: currentRow ?? this.currentRow,
      currentCol: currentCol ?? this.currentCol,
      position: position ?? this.position,
      size: size,
      clipPath: clipPath,
      isPlaced: isPlaced ?? this.isPlaced,
      isSelected: isSelected ?? this.isSelected,
      isLocked: isLocked ?? this.isLocked,
      rotation: rotation ?? this.rotation,
      zIndex: zIndex ?? this.zIndex,
    );
  }
  
  /// 移动到指定位置
  PuzzlePiece moveTo(ui.Offset newPosition) {
    return copyWith(position: newPosition);
  }
  
  /// 放置到指定网格位置（GameViewModel需要的方法）
  PuzzlePiece placeAt(int row, int col) {
    return copyWith(
      currentRow: row,
      currentCol: col,
      isPlaced: true,
    );
  }
  
  /// 移动到散落区域（GameViewModel需要的方法）
  PuzzlePiece moveToScatterArea(ui.Offset scatterPosition) {
    return copyWith(
      currentRow: -1,
      currentCol: -1,
      position: scatterPosition,
      isPlaced: false,
    );
  }
  
  /// 吸附到正确位置
  PuzzlePiece snapToCorrectPosition() {
    return copyWith(
      position: correctScreenPosition,
      isPlaced: true,
      isLocked: true,
      currentRow: correctRow,
      currentCol: correctCol,
    );
  }
  
  /// 选中状态切换
  PuzzlePiece toggleSelection() {
    return copyWith(isSelected: !isSelected);
  }
  
  @override
  List<Object?> get props => [
    id,
    image,
    currentRow,
    currentCol,
    position,
    isPlaced,
    isSelected,
    isLocked,
    rotation,
    zIndex,
  ];
  
  @override
  String toString() => 'PuzzlePiece('
      'id: $id, '
      'correct: ($correctRow, $correctCol), '
      'current: ($currentRow, $currentCol), '
      'position: $position, '
      'isPlaced: $isPlaced)';
}

/// 拼图块工厂类
/// 负责创建标准化的拼图块实例
/// 注意：这个工厂类现在无法创建带有 `image` 的 PuzzlePiece，
/// 因为它没有 `ui.Image` 数据源。实际的创建逻辑已经转移到 PuzzleGeneratorService。
/// 保留它是为了避免其他地方的引用报错。
class PuzzlePieceFactory {
  /// 创建基础矩形拼图块（V1.0版本）
  /// 注意：此方法已过时，因为它无法提供 image 字段
  static PuzzlePiece createBasicPiece({
    required int id,
    required int row,
    required int col,
    required ui.Size pieceSize,
    required ui.Offset initialPosition,
    required ui.Image image, // 临时添加一个 image 参数以避免编译错误
  }) {
    // 创建简单的矩形路径
    final clipPath = ui.Path()
      ..addRect(ui.Rect.fromLTWH(0, 0, pieceSize.width, pieceSize.height));
    
    return PuzzlePiece(
      id: id,
      correctRow: row,
      correctCol: col,
      image: image, // 使用传入的 image
      currentRow: -1, // 初始时在散落区域
      currentCol: -1,
      position: initialPosition,
      size: pieceSize,
      clipPath: clipPath,
    );
  }
  
  /// 创建传统拼图形状的拼图块（V2.0版本预留）
  /// 注意：此方法已过时
  static PuzzlePiece createJigsawPiece({
    required int id,
    required int row,
    required int col,
    required int totalRows,
    required int totalCols,
    required ui.Size pieceSize,
    required ui.Offset initialPosition,
    required ui.Image image, // 临时添加一个 image 参数以避免编译错误
  }) {
    // V2.0 版本将实现真正的拼图形状生成
    final clipPath = _generateJigsawShape(
      row, col, totalRows, totalCols, pieceSize);
    
    return PuzzlePiece(
      id: id,
      correctRow: row,
      correctCol: col,
      image: image, // 使用传入的 image
      currentRow: -1, // 初始时在散落区域
      currentCol: -1,
      position: initialPosition,
      size: pieceSize,
      clipPath: clipPath,
    );
  }
  
  /// 生成拼图形状路径（V2.0版本的核心算法）
  static ui.Path _generateJigsawShape(
    int row, int col, int totalRows, int totalCols, ui.Size size) {
    // V1.0版本先返回简单矩形，V2.0版本将实现复杂的拼图形状
    return ui.Path()..addRect(ui.Rect.fromLTWH(0, 0, size.width, size.height));
  }
}
